package kalender.backend;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.TransactionRequiredException;


@Entity
public class Event {
	private int eid;
	private Luser uid;
	private boolean pubshare;
	private EventType etype;
	private String e_desc;
	private java.util.Date start_ts;
	private java.util.Date stop_ts;
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY )
	public int getEid() { return eid; }
	public void setEid(int e) { eid = e; }
	
	@OneToOne
	@JoinColumn(name="etype")
	public EventType getEtype() { return etype; }
	public void setEtype(EventType et) { etype = et; }
	
	@OneToOne
	@JoinColumn(name="uid")
	public Luser getUid() { return uid; }
	public void setUid(Luser u) { uid = u; }
	
	public String getE_desc() { return e_desc; } 
	public void setE_desc(String e) { e_desc = e; }
	
	public boolean getPubshare() { return pubshare; }
	public void setPubshare(boolean pub) { pubshare = pub; }
	
	@Temporal(TemporalType.TIMESTAMP)
	public java.util.Date getStart_ts() { return start_ts; }
	public void setStart_ts(java.util.Date ts) { start_ts = ts; }
	
	@Temporal(TemporalType.TIMESTAMP)
	public java.util.Date getStop_ts() { return stop_ts; }
	public void setStop_ts(java.util.Date ts) { stop_ts = ts; }
	
	public String toString() { return "eid: " + eid + " uid: " + uid + " pubshare: " + pubshare + " etype " + etype + " e_desc: " + e_desc + " start_ts:  " + start_ts + " stop_ts: " + stop_ts; }
	
	public static Event find(int eid) throws BackendException {
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			return em.find(Event.class, eid);
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static List<Event> findAll() throws BackendException {
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			Query q = em.createQuery("select e from Event e");
			return q.getResultList();
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}

	@SuppressWarnings("unchecked")
	public static List<Event> findPublicByDate(java.util.Date start, java.util.Date stop) throws BackendException { 
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			Query q = em.createQuery("select e from Event e where e.start_ts between ?1 and ?2 and e.pubshare = TRUE order by e.start_ts");
			q.setParameter(1, start);
			q.setParameter(2, stop);
			return q.getResultList();
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		} catch (IllegalArgumentException e) {
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static List<Event> findByUserAndDate(Luser user, java.util.Date start, java.util.Date stop) throws BackendException { 
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			Query q = em.createQuery("select e from Event e where e.uid = ?1 and e.start_ts between ?2 and ?3 order by e.start_ts");
			q.setParameter(1, user);
			q.setParameter(2, start);
			q.setParameter(3, stop);
		return q.getResultList();
		} catch (IllegalStateException e) { 
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}

        @SuppressWarnings("unchecked")
	public static List<Event> findByUser(Luser user) throws BackendException {
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			Query q = em.createQuery("select e from Event e where e.uid = ?1 order by e.start_ts");
			q.setParameter(1, user);
		return q.getResultList();
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);
		}
	}
	
	public void saveNew() throws BackendException {
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			
			em.getTransaction().begin();
			
			em.persist(this);
			
			em.getTransaction().commit();
			
			em.close();
			factory.close();
		} catch (EntityExistsException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (TransactionRequiredException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);		
		}
	}
	
	public void saveUpdate() throws BackendException {
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			
			em.getTransaction().begin();
			
			em.merge(this);
			
			em.getTransaction().commit();
			
			em.close();
			factory.close();
		} catch (EntityExistsException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (TransactionRequiredException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);		
		}
	}
	
	public static void delete(int eid) throws BackendException {
		try {
			EntityManagerFactory factory = Persistence.createEntityManagerFactory("derp");
			EntityManager em = factory.createEntityManager();
			
			em.getTransaction().begin();
			
			Event t = em.find(Event.class, eid);
			em.remove(t);
			
			em.getTransaction().commit();
			
			em.close();
			factory.close();
		}  catch (EntityExistsException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (IllegalStateException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (IllegalArgumentException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);			
		} catch (TransactionRequiredException e) {
            e.printStackTrace();
			throw new BackendException("Databasfel. Var god försök igen.", e);		
		}
	}
}
